From 530e5f3e19e5e976c39c1a9e51260d2ee6d4c113 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 11 Aug 2014 17:05:22 -0700 Subject: [PATCH] Take a different strategy than ^{object} Apparently that syntax only exists in more recent versions of git, not older versions (like those present on the buildbots). --- src/cargo/sources/git/utils.rs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/cargo/sources/git/utils.rs b/src/cargo/sources/git/utils.rs index 5a42d46f0..fec0b23ed 100644 --- a/src/cargo/sources/git/utils.rs +++ b/src/cargo/sources/git/utils.rs @@ -152,11 +152,22 @@ impl GitRemote { pub fn rev_for(&self, path: &Path, reference: S) -> CargoResult { - // Make sure we only rev-parse a success if the reference is actually - // an object in the git database. Git will otherwise just verify that - // it's a 40-length hex string (almost always true) - let reference = format!("{}^{{object}}", reference.as_slice()); - Ok(GitRevision(git_output!(*path, "rev-parse", reference.as_slice()))) + // We simultaneously want to transform the reference into a resolved + // revision as well as verify that the reference itself is inside the + // repository. Sadly for a 40-character SHA1 the call to `rev-parse` + // will *always* return the same string with a 0 exit status, regardless + // of whether it's present in the database. + // + // Later versions of git introduced a syntax for this query via + // `$sha1^{object}`, but older versions of git do not support this. To + // get around this limitation, we chop 40-character sha revisions to 39 + // characters to get an error'd exit status if the revision is indeed + // not present. + let mut reference = reference.as_slice(); + if reference.len() == 40 { + reference = reference.slice_to(39); + } + Ok(GitRevision(git_output!(*path, "rev-parse", reference))) } pub fn checkout(&self, into: &Path) -> CargoResult { -- 2.30.2